﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using Newtonsoft.Json.Serialization;
using Sustainalytics.ESGRatings.Computing.Entities;
using Sustainalytics.ESGRatings.Computing.Entities.ESG;
using Sustainalytics.ESGRatings.DataContract;



using Xunit;
using System.Threading.Tasks;
using System.Text;
using System.Web;
using Newtonsoft.Json;

namespace Sustainalytics.ESGComputing.Service.Tests
{
    /// <summary>
    ///     Summary description for ESGClientTests
    /// </summary>
    public class ESGClientCRUDTests
    {
        private const string ConnectionString = "mongodb://localhost:27017/ClientDW_B";

        private static readonly JsonMediaTypeFormatter _jsonMediaTypeFormatter = new JsonMediaTypeFormatter
        {
            SerializerSettings = { ContractResolver = new CamelCasePropertyNamesContractResolver() }
        };

        private static readonly HttpClient _sutClient = new HttpClient();
        private static readonly string _serviceLink = "http://localhost:10280/esgcomputingserv/api/v1/";
        private static readonly string _sutLink = _serviceLink + "dataprovisioning/esgsets";

        public class ESGClient_CleanContext
        {
            private readonly IList<Guid> _companyIds = new[]
            {
                new Guid("00000000-0000-0000-0000-000000000001"), new Guid("00000000-0000-0000-0000-000000000002"),
                new Guid("00000000-0000-0000-0000-000000000003")
            };

            private readonly Guid _matrixId = new Guid("00000000-0000-0000-0000-000000000004");
            private readonly Guid _referenceUniversesId = new Guid("00000000-0000-0000-0000-000000000005");

            [Fact]
            public void Add_Set_And_Clean_Context_Test()
            {
                var testSet = new ESGDataContainer
                {
                    IndicatorTemplates = GetIndicatorConfiguration(),
                    Companies = GetCorporateData().ToArray(),
                    CompaniesScores =
                        GetIndicatorsData()
                            .Select(
                                x =>
                                    new CompanyScores(x.CompanyId,
                                        x.Data.Select(y => new IndicatorDefaultScore(y.Key, (int)y.Value))))
                            .ToArray()
                };


                var matrixWeights = from weight in GetCompanyWeightsData()
                                    select
                                        new CompanyWeights
                                        {
                                            CompanyId = weight.CompanyId,
                                            IndicatorsData = weight.IndicatorsData.Select(x => new Weight(x.Code, x.Value))
                                        };

                testSet.Matrices = new[]
                {
                    new WeightMatrix
                    {
                        AccountId = Guid.NewGuid(),
                        MatrixId = _matrixId,
                        CompaniesWeights = matrixWeights.ToArray()
                    }
                };

                testSet.ReferenceUniverses = new[] { GetReferenceUniverse() };

                var task = _sutClient.PostAsync(_sutLink, testSet, _jsonMediaTypeFormatter);
                var insertedGuid = task.Result.Content.ReadAsAsync<Guid>(_jsonMediaTypeFormatter.Yield()).Result;

                var taskClean = _sutClient.PostAsync($"{_serviceLink}health/clean", string.Empty,
                    _jsonMediaTypeFormatter);

                var result = taskClean.Result.Content.ReadAsAsync<IEnumerable<Guid>>(_jsonMediaTypeFormatter.Yield()).Result;

                Assert.NotNull(result);
                Assert.True(result.Contains(insertedGuid));

            }

            private IEnumerable<CompanyWeights> GetCompanyWeightsData()
            {
                return new List<CompanyWeights>
                {
                    new CompanyWeights
                    {
                        CompanyId = _companyIds[0],
                        IndicatorsData = new Dictionary<string, float>
                        {
                            {"E.1.1", 0.1f},
                            {"E.1.2", 0},
                            {"E.1.12", 0.15f},
                            {"E.2.2", 0},
                            {"E.1.4", 0},
                            {"G.1.4", 0},
                            {"G.1.1", 0.2f},
                            {"S.1.1", 0.25f},
                            {"S.1.2", 0.3f}
                        }.Select(x => new Weight(x.Key, x.Value))
                    },
                    new CompanyWeights
                    {
                        CompanyId = _companyIds[2],
                        IndicatorsData = new Dictionary<string, float>
                        {
                            {"E.1.1", 0},
                            {"E.1.2", 0},
                            {"E.1.12", 0.1f},
                            {"E.2.2", 0.15f},
                            {"E.1.4", 0.1f},
                            {"G.1.4", 0.15f},
                            {"G.1.1", 0.15f},
                            {"S.1.1", 0.23f},
                            {"S.1.2", 0.12f}
                        }.Select(x => new Weight(x.Key, x.Value))
                    },
                    new CompanyWeights
                    {
                        CompanyId = _companyIds[1],
                        IndicatorsData = new Dictionary<string, float>
                        {
                            {"E.1.1", 0},
                            {"E.1.2", 0.05f},
                            {"E.1.12", 0.1f},
                            {"E.2.2", 0f},
                            {"E.1.4", 0.00f},
                            {"G.1.4", 0.1f},
                            {"G.1.1", 0.2f},
                            {"S.1.1", 0.25f},
                            {"S.1.2", 0.3f}
                        }.Select(x => new Weight(x.Key, x.Value))
                    }
                };
            }

            private IEnumerable<CompanyData> GetCorporateData()
            {
                var companies = new List<CompanyData>
                {
                    new CompanyData()
                    {
                        Id = _companyIds[0],
                        CompanyType = "public",TemplateType = "Type A",
                        IndustryGroup = "Banks",
                        PeerGroup = "Banks"
                    },
                    new CompanyData
                    {
                        Id = _companyIds[1],
                         CompanyType = "public",TemplateType = "Type A",
                        IndustryGroup = "Diversified Financials",
                        PeerGroup = "Diversified Financials"
                    }
                    ,
                    new CompanyData
                    {
                        Id = _companyIds[2],
                         CompanyType = "public",TemplateType = "Type A",
                        IndustryGroup = "Diversified Financials",
                        PeerGroup = "Diversified Financials"
                    }
                };
                return companies;
            }

            private IndicatorTemplate[] GetIndicatorConfiguration()
            {
                IndicatorTemplate[] builder =
                {
                    new IndicatorTemplate("E.1.1", "E", "P​​"),
                    new IndicatorTemplate("E.1.2",
                        "E", "P​​"),
                    new IndicatorTemplate("E.1.12",
                        "E", "QLP"),
                    new IndicatorTemplate("E.2.2",
                        "E", "QLP"),
                    new IndicatorTemplate("E.1.4",
                        "E", "QNP"),
                    new IndicatorTemplate("G.1.4",
                        "G", "D"),
                    new IndicatorTemplate("G.1.1",
                        "G", "P​​"),
                    new IndicatorTemplate("S.1.1",
                        "S", "P​​"),
                    new IndicatorTemplate("S.1.2",
                        "S", "QLP")
                };
                return builder;
            }

            private List<IndicatorsData> GetIndicatorsData()
            {
                return new List<IndicatorsData>
                {
                    new IndicatorsData
                    {
                        CompanyId = _companyIds[0],
                        Data = new[]
                        {
                            new KeyValuePair<string, float>("E.1.1", 100),
                            new KeyValuePair<string, float>("E.1.2", 0),
                            new KeyValuePair<string, float>("E.1.12", 50),
                            new KeyValuePair<string, float>("E.2.2", 20),
                            new KeyValuePair<string, float>("E.1.4", 0),
                            new KeyValuePair<string, float>("G.1.4", 90),
                            new KeyValuePair<string, float>("G.1.1", 50),
                            new KeyValuePair<string, float>("S.1.1", 20),
                            new KeyValuePair<string, float>("S.1.2", 30)
                        }
                    },
                    new IndicatorsData
                    {
                        CompanyId = _companyIds[2],
                        Data = new[]
                        {
                            new KeyValuePair<string, float>("E.1.1", 50),
                            new KeyValuePair<string, float>("E.1.2", 40),
                            new KeyValuePair<string, float>("E.1.12", 100),
                            new KeyValuePair<string, float>("E.2.2", 100),
                            new KeyValuePair<string, float>("E.1.4", 0),
                            new KeyValuePair<string, float>("G.1.4", 80),
                            new KeyValuePair<string, float>("G.1.1", 50),
                            new KeyValuePair<string, float>("S.1.1", 20),
                            new KeyValuePair<string, float>("S.1.2", 30)
                        }
                    },
                    new IndicatorsData
                    {
                        CompanyId = _companyIds[1],
                        Data = new[]
                        {
                            new KeyValuePair<string, float>("E.1.1", 0),
                            new KeyValuePair<string, float>("E.1.2", 10),
                            new KeyValuePair<string, float>("E.1.12", 20),
                            new KeyValuePair<string, float>("E.2.2", 0),
                            new KeyValuePair<string, float>("E.1.4", 0),
                            new KeyValuePair<string, float>("G.1.4", 50),
                            new KeyValuePair<string, float>("G.1.1", 75),
                            new KeyValuePair<string, float>("S.1.1", 25),
                            new KeyValuePair<string, float>("S.1.2", 75)
                        }
                    }
                };
            }

            private ReferenceUniverse GetReferenceUniverse()
            {
                return new ReferenceUniverse
                {
                    Id = _referenceUniversesId,
                    Companies = new[]
                    {
                        new ReferenceUniverseCompany
                        {
                            CapitalIQID = "IQ20704112",
                            CompanyId = _companyIds[0],
                            CompanyName = "Compania1"
                        },
                        new ReferenceUniverseCompany
                        {
                            CapitalIQID = "IQ20704113",
                            CompanyId = _companyIds[1],
                            CompanyName = "Compania2"
                        }
                    }
                };
            }
        }



        public class ESGClientDataContainerCRUDTests
        {

            [Fact]
            public async Task Given_A_Set_Should_Change_The_Status_Of_Default_Set()
            {

                var method = new HttpMethod("PATCH");
                var SetId = new Guid("79a97289-5d47-490f-85b1-7c54d3629293");

                var request = new HttpRequestMessage(method, new Uri(_sutLink))
                {
                    Content = new StringContent(JsonConvert.SerializeObject(new ESGDataContainerDTO { setId = SetId, isActive = true }), Encoding.UTF8, "application/json")
                };

                var response = await _sutClient.SendAsync(request).ConfigureAwait(false);

                Assert.True(response.IsSuccessStatusCode);
            }


        }
    }
}